package com.imooc.gateway.config;

import cn.dev33.satoken.httpauth.basic.SaHttpBasicUtil;
import cn.dev33.satoken.jwt.StpLogicJwtForStateless;
import cn.dev33.satoken.reactor.filter.SaReactorFilter;
import cn.dev33.satoken.router.SaRouter;
import cn.dev33.satoken.stp.StpLogic;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.server.ServerWebExchange;
import cn.dev33.satoken.context.SaHolder;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * [Sa-Token 权限认证] 配置类 
 * @author click33
 */
@Configuration
public class SaTokenConfigure {
    // 注册 Sa-Token全局过滤器 
    @Bean
    public SaReactorFilter getSaReactorFilter() {
        return new SaReactorFilter()
            // 拦截地址 
            .addInclude("/**")    /* 拦截全部path */
            // 开放地址 
            .addExclude("/favicon.ico")
            .addExclude("/user/doLogin")
            // 鉴权方法：每次访问进入 
            .setAuth(obj -> {
                String path = SaHolder.getRequest().getRequestPath();
                System.out.println(path);
                // 登录校验 -- 拦截所有路由，并排除/user/doLogin 用于开放登录
                SaRouter.match("/**",  r -> StpUtil.checkLogin());

                // 权限认证 -- 不同模块, 校验不同权限
                SaRouter.match("/user/**",r -> StpUtil.checkPermission("user"));
//                SaRouter.match("/admin/**", r -> StpUtil.checkPermission("admin"));
//                SaRouter.match("/goods/**", r -> StpUtil.checkPermission("goods"));
                SaRouter.match("/order/**", r -> StpUtil.checkPermission("orders"));
                String tenantCode = SaHolder.getRequest().getHeader("user-agent");
                System.out.println(tenantCode);
                // 动态加载拦截规则
                /*Map<String, String> authRules = getAuthRules();
                for (String path : authRules.keySet()) {
                    SaRouter.match(path, () -> StpUtil.checkPermission(authRules.get(path)));
                }*/
            })
            // 异常处理方法：每次setAuth函数出现异常时进入 
            .setError(e -> {
                return SaResult.error(e.getMessage());
            });
    }
    // 动态获取鉴权规则
    private Map<String, String> getAuthRules() {
        Map<String, String> authMap = new LinkedHashMap<>();
        authMap.put("/user/**", "user");
        authMap.put("/admin/**", "admin");
        authMap.put("/article/**", "article");
        // 更多规则 ...
        return authMap;
    }

    // Sa-Token 整合 jwt (Stateless 无状态模式)
    @Bean
    public StpLogic getStpLogicJwt() {
        return new StpLogicJwtForStateless();
    }
}

